home *** CD-ROM | disk | FTP | other *** search
- // **************************************************************************
-
- #include <graphics.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <conio.h>
-
- #include "template.h"
- #include "svga256.h"
-
- typedef double flyt;
- typedef unsigned int word;
- typedef unsigned char byte;
-
- #define FRAMES 44 // Number of times the resolution is doubled
- #define EXT 192 // Size of window, in pixels
- #define VIEW 2.5
- #define EXTPARTS 6
- #define FX2 -1.38138562516074
- #define FY2 0.09709670415710
- #define POLKADOT -EXT/2
-
- #define FILTER 1
-
- #define FX2 -1.67470096283140
- #define FY2 0.00006950133713
-
- #define FX2 -0.82226457050119
- #define FY2 0.17599715464079
-
- #define LIMIT 10
-
- #define LX -1
- #define LY 0.5
- #define LZ 1
-
- #define RAD 50
- #define PI 3.1415926535
- #define RATIO 1
-
- float rgbplussr,rgbfacr=4.4,rgbplussg,rgbfacg=7.8,rgbplussb,rgbfacb=11.3;
- int globalblank=0;
-
- // DETECTVGA
-
- int huge DetectVGA256(void) {return 4;}
-
- int data004[10000];
- int maxused=0,maxcol=20;
-
- word diffno[512],diffnum=0,feil;
-
- // GRAFIKK
-
- void grafikk(void)
- {
- int gd=DETECT, Gm;
- installuserdriver("Svga256",DetectVGA256);
- initgraph(&gd,&Gm,"");
- for (int teller=1; teller<256; teller++)
- {
- setpalette(teller,teller);
-
- flyt r=sin(rgbplussr+teller*rgbfacr*PI/255);
- flyt g=sin(rgbplussg+teller*rgbfacg*PI/255);
- flyt b=sin(rgbplussb+teller*rgbfacb*PI/255);
-
- r=fabs(r)*63;
- g=fabs(g)*63;
- b=fabs(b)*63;
-
- setrgbpalette(teller,r,g,b);
- setcolor(teller);
- line(1000,teller*2,1023,teller*2);
- }
- }
-
- // WPUTPIXEL
-
- void wputpixel(int x,int y,byte color, byte vindu)
- {
- if (x>319 || x<0 || y>239 || y<0)
- return;
- putpixel(x+350*(vindu%3),y+100+250*(vindu/3),color);
- }
-
- // WGETPIXEL
-
- byte wgetpixel(int x,int y,byte vindu)
- {
- if (x>320 || x<0 || y>240 || y<0)
- return 0;
- return getpixel(x+350*(vindu%3),y+100+(vindu/3)*250);
- }
-
- // RECTANGLE
-
- void wrectangle(int x0,int y0,int x1,int y1,byte color,
- byte vindu,byte pluss=0)
- {
- for (int y=y0; y<=y1; y++,color+=pluss)
- for (int x=x0; x<=x1; x++)
- wputpixel(x,y,color,vindu);
- }
-
- // DIFF
-
- void diff(byte w1,byte w2,byte w3)
- {
- for (int x=0; x<EXT; x++)
- for (int y=0; y<EXT; y++)
- {
- byte no1=wgetpixel(x,y,w1);
- byte no2=wgetpixel(x,y,w2);
- byte dino=no1-no2;
- if (dino)
- {
- feil++;
- diffno[dino]++;
- putpixel(960l-(diffno[dino]/20),dino+65,40);
- wputpixel(x,y,no2+dino,w1);
- diffnum++;
- }
- wputpixel(x,y,dino,w3);
- }
- }
-
- // KUGEL
-
-
- void kugel(float rad=RAD)
- {
- long pix=0,shad=0;
- for (float x=-rad; x<=rad; x++)
- for (float y=-rad; y<=rad; y++)
- if (x*x+y*y<rad*rad)
- {
- pix++;
- float dx=x/rad;
- float dy=y/rad;
- float dz=sqrt(1-dx*dx-dy*dy);
- float ny=(dx*LX)+(dy*LY)+(dz*LZ);
- int shade=0;
- if (ny<=0)
- {
- ny=0;
- shade=1;
- }
- ny+=random(100)/3000.0;
- shad+=shade;
- ny=17*ny+12;
- for (int xx=0; xx<RATIO; xx++)
- for (int yy=0; yy<RATIO; yy++)
- putpixel(x*RATIO+xx+RATIO*rad,y*RATIO+yy+RATIO*rad,ny);
- }
- for (x=-rad; x<=rad; x++)
- for (float y=-rad; y<=rad; y++)
- putpixel(x+500,y+200,getpixel(x+rad,y+rad));
- for (x=-rad; x<=rad; x++)
- for (float y=-rad; y<=rad; y++)
- {
- int fac[]={2,3,2,3,6,3,2,3,2};
- int col=0;
- int teller=0;
- for (int dx=-1; dx<=1; dx++)
- for (int dy=-1; dy<=1; dy++)
- col+=fac[teller++]*getpixel((x+dx)+500,(y+dy)+200);
- if (col<8*26)
- col=0;
- for (int xx=0; xx<3; xx++)
- for (int yy=0; yy<3; yy++)
- if (col)
- {
- putpixel((x+rad)*3+xx,(y+rad)*3+yy,col/26);
- putpixel((x+rad)*3+xx+28,(y+rad)*3+yy+36,col/26);
- putpixel((x+rad)*3+xx+12,(y+rad)*3+yy+84,col/26);
- }
- }
-
- }
-
- void mult(flyt &x,flyt &y,flyt x2,flyt y2)
- {
- flyt nx=x*x2-y*y2;
- y=x*y2+x2*y;
- x=nx;
- }
-
- // FCOL
-
- // Here's where the fractal values are calculated.
-
- byte fcolor(flyt x,flyt y)
- {
- flyt xx,yy;
- xx=0;
- yy=0;
- int iter=0;
- while(1)
- {
- iter++;
- if (iter>=maxcol)
- return 0;
- mult(xx,yy,xx,yy);
- xx+=x;
- yy+=y;
- if (xx*xx+yy*yy>LIMIT)
- goto done;
- }
- done:
- if (iter<maxcol && iter>maxused)
- {
- maxcol=iter+40;
- maxused=iter;
- putpixel(975,iter,200);
- }
- return iter;
- }
-
- void fract(flyt x,flyt y,flyt width,int vindu=0)
- {
- flyt top=y-width;
- flyt left=x-width;
- flyt step=2*width/EXT;
- flyt xx,yy=top;
- for (int tx=0; tx<EXT; tx++)
- {
- xx=left;
- for(int ty=0; ty<EXT; ty++)
- {
- int blank=globalblank;
- for (int rx=-2; rx<=2 && blank; rx++)
- for (int ry=-2; ry<=2 && blank; ry++)
- blank&=(!wgetpixel(tx+rx,ty+ry,2));
- byte c;
- if (!blank)
- c=fcolor(xx,yy);
- else
- c=0;
- wputpixel(tx,ty,c,vindu);
- xx+=step;
- }
- yy+=step;
- }
- wputpixel(POLKADOT,POLKADOT,100,vindu);
- }
-
- // COPY
-
- void copy(int from,int to)
- {
- for (int teller=0; teller<EXT; teller++)
- for (int t=0; t<EXT; t++)
- wputpixel(teller,t,wgetpixel(teller,t,from),to);
- }
-
- // ZOOM
-
- void zoom(int from,int to)
- {
- for (int x=0; x<EXT/2; x++)
- for (int y=0; y<EXT/2; y++)
- {
- int c=wgetpixel(x+EXT/4,y+EXT/4,from);
- for (int xx=0; xx<2; xx++)
- for (int yy=0; yy<2; yy++)
- wputpixel(x*2+xx,y*2+yy,c,to);
- }
- }
-
- // PUSHBIT
-
- long pushbit(FILE *fp, word bit)
- {
- static long len=0;
- static byte data=0,count=0;
- if (bit==54321)
- {
- len=count=0;
- return 0;
- }
- if (bit==43198 && !count)
- return len;
- emptyit:
- data<<=1;
- data|=(bit&1);
- count++;
- if (count==8)
- {
- fwrite(&data,1,1,fp);
- len++;
- data=count=0;
- }
- if (bit==43198 && count)
- goto emptyit;
- return len;
- }
-
- // PUSHMODE
-
- void pushmode(byte data,byte len,FILE *fp)
- {
- for (int teller=0; teller<len; teller++)
- {
- pushbit(fp,data&1);
- data>>=1;
- }
- }
-
- // MAKEDATA
-
- void makedata(int x,int y,int br, FILE *fp)
- {
- if (br>1)
- {
- for (int yy=0; yy<2; yy++)
- for (int xx=0; xx<2; xx++)
- {
- int hit=0;
- for (int scx=0; scx<br/2; scx++)
- for (int scy=0; scy<br/2; scy++)
- {
- byte col=wgetpixel(x+xx*br/2+scx,y+yy*br/2+scy,3);
- if (col)
- {
- hit=1;
- goto hitsomething;
- }
- }
- hitsomething:
- if (hit)
- {
- pushbit(fp,1);
- makedata(x+xx*br/2,y+yy*br/2,br/2,fp);
- }
- else
- pushbit(fp,0);
-
- }
- }
- else
- {
- byte col=wgetpixel(x,y,3);
- if (col==1)
- {
- pushbit(fp,1);
- pushbit(fp,1);
- }
- else
- if (col==255)
- {
- pushbit(fp,1);
- pushbit(fp,0);
- }
- else
- {
- pushbit(fp,0);
- if (col<10)
- {
- pushbit(fp,1);
- pushmode(col-2,3,fp);
- }
- else
- if (col>247)
- {
- pushbit(fp,0);
- pushmode(col-247,3,fp);
- }
- else
- {
- pushbit(fp,0);
- pushmode(0,3,fp);
- pushmode(col,8,fp);
- }
- }
- wputpixel(x,y,40,3);
- }
- }
-
- // SAVEDIFF
-
- void savediff(FILE *fp)
- {
- for (int y=0; y<EXTPARTS; y++)
- for (int x=0; x<EXTPARTS; x++)
- {
- makedata(x*(EXT/EXTPARTS),y*(EXT/EXTPARTS),EXT/EXTPARTS,fp);
- pushbit(fp,43198);
- }
- }
-
- // MAKEFRACDATA
-
- void makefracdata(void)
- {
- char *text="01";
- FILE *bitdata=fopen("LIGHTC.005","wb");
- FILE *o06=fopen("LIGHTC.007","wb");
- for (int bl=0; bl<255; bl++)
- diffno[bl]=0;
- feil=0;
- flyt initwidth=VIEW;
- for (int teller=0; teller<FRAMES; teller++)
- {
- for (int uu=0; uu<10; uu++)
- for (int ii=0; ii<30; ii++)
- putpixel(ii,uu,0);
- outtextxy(0,0,text);
- text[1]++;
- if (text[1]==58)
- {
- text[0]++;
- text[1]=48;
- }
-
- fract(FX2,FY2,initwidth,0);
- if (!teller)
- {
- FILE *dump=fopen("LIGHTC.006","wb");
- for (int teller=0; teller<EXT; teller++)
- for (int t=0; t<EXT; t++)
- {
- byte c=wgetpixel(teller,t,0);
- c^=(teller+t);
- fwrite(&c,1,1,dump);
- }
- fclose(dump);
- }
- zoom(1,2);
- if (teller)
- {
- globalblank=1;
- #if FILTER
- byte spaadd;
- for (int x=0; x<320; x++)
- for (int y=0; y<240; y++)
- {
- byte here=wgetpixel(x,y,0);
- if (!here)
- if ((spaadd=wgetpixel(x,y,2))!=here)
- if (here!=wgetpixel(x-1,y,0))
- if (here!=wgetpixel(x+1,y,0))
- if (here!=wgetpixel(x,y+1,0))
- if (here!=wgetpixel(x,y-1,0))
- wputpixel(x,y,spaadd,0);
- }
- #endif
-
- diff(0,2,3);
- savediff(bitdata);
- }
- initwidth/=2;
- copy(0,1);
- zoom(0,2);
- int len;
- if (teller)
- {
- len=pushbit(bitdata,43198);
- fwrite(&len,1,2,o06);
- pushbit(bitdata,54321);
- }
- }
- fclose(bitdata);
- fclose(o06);
- }
-
- // MAIN
-
- void main(void)
- {
- grafikk();
- makefracdata();
- }
-
- /*
-
- VINDUSFORDELING:
-
- 0 - SKIKKELIG BILDE
- 1 - FORRIGE BILDE
- 2 - ZOOM PAA FORRIGE BILDE
-
- FORMAT, DATAFILER:
- ******************
-
- .004
- ----
-
- * Antall bytes i tilh0rende nedpakkede bilde i 005 (word)
- * Antall direkte kopier som skal foretas fra originalt bilde (word)
- * Peker til originalt bilde (word)
- * Peker til posisjon i nytt bilde (word)
- * Bredde (byte)
- * H0yde (byte)
- * Antall direkte kopier som skal foretas innen det nye bildet, etter at
- finjusteringa er foretatt (word)
- * Peker til nytt bilde (word)
- * Peker til posisjon i nytt bilde (word)
- * Bredde (byte)
- * H0yde (byte)
-
- FILE.005
- --------
-
- * Within each XXxYY block:
- ? x 4 (2)
- ? x 16 (4)
- ? x 64 (8)
- ? x (16)
- ? x (32)
- ? x 4096 (64)
-
- The data is then aligned to the next byte after each block
-
- .006 Original bmp
-
- The animation is run in this way:
-
- There is always two completed image A and B) stored in memory.
- The actual zooming is simply a matter of making a smooth transition from
- one picture to the other (simple scaling). A third image (C) is gradually
- decompressed in the background. At the moment this is done, the program
- copies the B-pointer to the A-pointer, the C-pointer to the B-pointer and
- resumes decompressing a new picture. (The uneven motion of the zoom is
- caused by a rounding error when combining picture A and B).
-
- The images themselves are compressed like this:
-
- 1. Take the center of the last image and scale it to a factor of two.
- 2. Subtract this image from the newly rendered one. This gives a heavy
- distribution of -1s, 0s and 1s.
- 3. This picture is recursively compressed by subdividing the area into
- smaller and smaller squares, with a 0 indicating an area where no change
- is needed.
- 4. At the end of each branch, the color is compressed with variable length
- encoding, using the following scheme:
-
- After every collision:
-
- 1 - 1 - 1
- 0 - 255
- 0 - 1 - 2->9
- 0 - 248->254
-
- A value of 248 -> read next 8 bits.
-
- (I didn't bother implementing Huffman encoding)
-
- All digits are stored low bit first, i.e bit 0-1-2-3-4-5-6-7
-
- */